package metu.tespit.session.util;

/**
 * Created with IntelliJ IDEA.
 * User: ekisa
 * Date: 08.06.2012
 * Time: 09:26
 * To change this template use File | Settings | File Templates.
 */
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;

import metu.tespit.entitiy.accountManagement.User;
import metu.tespit.entity.course.Activity;
import metu.tespit.entity.course.ProjectDocument;
import metu.tespit.entity.course.ProjectTeam;
import metu.tespit.entity.semester.Semester;
import metu.tespit.session.projectteam.ProjectTeamHome;
import metu.tespit.session.schedule.ActivityHome;

import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.async.Asynchronous;
import org.jboss.seam.annotations.async.Expiration;
import org.jboss.seam.annotations.async.IntervalCron;
import org.jboss.seam.async.QuartzTriggerHandle;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.faces.Renderer;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

import javax.persistence.EntityManager;
import javax.persistence.TemporalType;

@Name("jobNotificationEmailsIncompleteActivity")
@AutoCreate
@Scope(ScopeType.APPLICATION)
public class JobNotificationEmailsIncompleteActivity {


    private User mailToUser;
    private Activity activity;
    private ProjectTeam projectTeam;

    @SuppressWarnings("unchecked")
	@Asynchronous
    public QuartzTriggerHandle createJobNotificationEmailsIncompleteActivity(
            @Expiration Date when, @IntervalCron String interval) {
        
    	EntityManager entityManager = (EntityManager) Component.getInstance("entityManager");
        Renderer renderer = (Renderer) Component.getInstance("org.jboss.seam.faces.renderer", true);
        ProjectTeamHome projectTeamHome = (ProjectTeamHome) Component.getInstance("projectTeamHome", true);
        
        DateTimeZone timeZone = DateTimeZone.forID("Europe/Istanbul");
		DateTime dateTime = new DateTime(timeZone);
		
		Semester activeSemester = null;
		List<Semester> semesters = (List<Semester>)entityManager.createQuery("from Semester s where s.startDate <= :now and s.endDate >= :now")
			.setParameter("now", new Date(), TemporalType.TIMESTAMP)
			.getResultList();
		if(semesters == null || semesters.size() == 0){
			return null;
		}else{
			activeSemester = semesters.get(0);
		}

        List<Activity> dueDateGecenActiviteler = (List<Activity>)entityManager.createQuery("from Activity a " +
        		"where a.schedule.course.semester.id = :activeSemester" +
	                " and a.dueDate < :now")
                .setParameter("activeSemester", activeSemester.getId())
                .setParameter("now", dateTime.toDate(), TemporalType.TIMESTAMP)
                .getResultList();
        
        for (Iterator iterator = dueDateGecenActiviteler.iterator(); iterator.hasNext(); ) {
            try {
                activity = (Activity) iterator.next();

                List<ProjectTeam> projectTeams = activity.getSchedule().getCourse().getProjectTeams();
                for (Iterator<ProjectTeam> projectTeamIterator = projectTeams.iterator(); projectTeamIterator.hasNext(); ) {
                    projectTeam = projectTeamIterator.next();
                    
                    //bu aktivite icin daha once mail atilmissa continue
                    if(projectTeam.getIncompleteActivities().contains(activity)){
                    	continue;
                    }
                    
                    boolean buActivityIcinUploadYapilmis = false;
                    for (Iterator<ProjectDocument> documentIterator = activity.getProjectDocuments().iterator(); documentIterator.hasNext();) {
						ProjectDocument document = documentIterator.next();
						if(document.uploadiBuProjectTeamMiYapmis(projectTeam)){
							buActivityIcinUploadYapilmis = true;
							break;
						}
					}
                    
                    if(buActivityIcinUploadYapilmis){
                    	//Bu aktivite icin project teamin uploadi var, mail atmaya gerek yok, diger project teame gec
                    	continue;
                    }
                    
                	//bunu sakla ki ayni aktivite icin iki kez mail atmayalim
                	this.markActivityAsSent(activity, projectTeam, projectTeamHome);
                	
                	//upload yapilmadigina dair Instructor ve Assistana mail ile bildirim yap
                	User instructor = activity.getSchedule().getCourse().getInstructor();
                	User teachingAssistant = activity.getSchedule().getCourse().getTeachingAssistant();
                    
                	this.mailAt(instructor, renderer);
                	this.mailAt(teachingAssistant, renderer);
                	
                	projectTeam = entityManager.find(ProjectTeam.class, projectTeam.getId());
                	this.mailAt(projectTeam, renderer);
                    
                }
                
            } catch (Exception e) {
                e.printStackTrace();
                //Hata alirsa bir sonraki activity icin dene
                this.markActivityAsSent(activity, projectTeam, projectTeamHome);
            }
        }

        return null;
    }
    
    private void mailAt(User user, Renderer renderer){
    	mailToUser = user;
    	//System.out.println("Mailing to " + user.getEmail());
    	renderer.render("/Mail/notificationEmailIncompleteActivity.xhtml");
    }
    
    private void mailAt(ProjectTeam projectTeam, Renderer renderer){
    	//project teamin kullanıcılarına mail at
        for (Iterator<User> userIterator = projectTeam.getStudents().iterator(); userIterator.hasNext(); ) {
            this.mailAt(userIterator.next(), renderer);
        }
    }
    
    private void markActivityAsSent(Activity activity, ProjectTeam projectTeam, ProjectTeamHome projectTeamHome){
    	projectTeam.getIncompleteActivities().add(activity);
    	projectTeamHome.setInstance(projectTeam);
    	projectTeamHome.persist();
    }

    public static String getCronInterval() {
        //return "0/30 * * * * ?"; // test etmek için every 30 second
        return "0 0 * * * ?"; //EVERY HOUR
    }

    public User getMailToUser() {
        return mailToUser;
    }

    public void setMailToUser(User mailToUser) {
        this.mailToUser = mailToUser;
    }

    public Activity getActivity() {
        return activity;
    }

    public void setActivity(Activity activity) {
        this.activity = activity;
    }

	public ProjectTeam getProjectTeam() {
		return projectTeam;
	}

	public void setProjectTeam(ProjectTeam projectTeam) {
		this.projectTeam = projectTeam;
	}
    
    
}
